#ifndef __BUOLA_GUI_CCLIPBOARD_H__
#define __BUOLA_GUI_CCLIPBOARD_H__

#include <buola/gui.h>
#include <buola/io/curi.h>

namespace buola { namespace gui {

///\addtogroup gui
///@{

////////////////////////////////////////////////////////////////////////////

/// clipboard

/// Represents shared storage which can be used to exchange data between
/// applications, usually by means of copy & paste.
///
/// \todo implement all the other data types
/// \todo complete documentation
///
////////////////////////////////////////////////////////////////////////////

class CClipboard : public UUncopiable
{
public:
    //! used to select which clipboard we want to use
    enum EWhich
    {
        CLIPBOARD,      //! main clipboard
        PRIMARY,        //! primary selection
        SECONDARY,      //! secondary selection
        DRAGNDROP,      //! drag and drop buffer
        CB_COUNT
    };

protected:
    //! internal data type
    enum EDataType
    {
        TYPE_TARGETS=1,
        TYPE_STRING=2,
        TYPE_URI=3,
        TYPE_IMAGE=4,
        TYPE_MIME=5
    };

protected:
//! \name constructor and destructor
//@{
    CClipboard(int pAtom);
    virtual ~CClipboard();
//@}

public:
//! \name server interface
//@{
    virtual bool IsOwned()=0;
    virtual bool OwnSelection()=0;
    virtual bool ReleaseSelection()=0;
    void SetString(const std::wstring &pContents);
    void SetURI(const io::CURI &pURI);
    void Clear();
//@}

//! \name client interface
//@{
    virtual void InitTargets()=0;
    virtual void AddTarget(const std::wstring&)=0;
    virtual void AskForSelection(int)=0;
    void RequestString(CClipboardTarget*);
    bool GetString(std::wstring&);
    void RequestURI(CClipboardTarget*);
    bool GetURI(io::CURI&);
//@}

protected:
//! \name server internal
//@{
    bool ProvideData(const std::wstring&);
    virtual void ServeText(const std::wstring&)=0;
//@}

//! \name client internal
//! \brief communicate with implementation details
//@{
    void SelectionReady(const std::wstring&);
    void SelectionFailed();
    void SelectionLost();
//@}

//! \name common data
//@{
    int mType;
//@}

//! \name server data
//@{
    int mContentsType;
    std::wstring mTextContents;
    io::CURI mURIContents;
    CClipboardSource *mSource;
//@}

//! \name client data
//@{
    std::wstring mReceivedContents;
    CClipboardTarget *mTarget;
    bool mDataReady;
    bool mDataFailed;
    bool mStopLoop;
//@}

    friend class CToolkit;
};

///@}

/*namespace gui*/ } /*namespace buola*/ }

#endif
